package com.ruoyi.system.utils;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.ComponentInfoExcel;
import com.ruoyi.system.domain.vo.ScaledImageDataDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.imgscalr.Scalr;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Objects;

@Slf4j
public class ComponentExcelUtils {

    public static Workbook generateWorkBook(String projectName, List<ComponentInfoExcel> dataList){
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet(projectName);

        // 创建单元格样式
        CellStyle headerStyle = workbook.createCellStyle();
        headerStyle.setAlignment(HorizontalAlignment.CENTER); // 设置水平居中
        headerStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 设置垂直居中

        CellStyle dataStyle = workbook.createCellStyle();
        dataStyle.setAlignment(HorizontalAlignment.LEFT); // 设置水平左对齐
        dataStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 设置垂直居中

        // 创建单元格样式
        CellStyle picStyle = sheet.getWorkbook().createCellStyle();
        picStyle.setAlignment(HorizontalAlignment.CENTER); // 设置水平居中
        picStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 设置垂直居中

        // 设置列宽
        sheet.setColumnWidth(0, 10 * 256); // 姓名列宽度
        sheet.setColumnWidth(1, 10 * 256); // 年龄列宽度
        sheet.setColumnWidth(2, 10 * 256); // 图片列宽度
        sheet.setColumnWidth(3, 10 * 256); // 姓名列宽度
        sheet.setColumnWidth(4, 10 * 256); // 年龄列宽度
        sheet.setColumnWidth(5, 10 * 256); // 图片列宽度
        sheet.setColumnWidth(6, 10 * 256); // 图片列宽度
        sheet.setColumnWidth(7, 10 * 256); // 图片列宽度
        sheet.setColumnWidth(8, 30 * 256); // 图片列宽度

        // 创建标题行
        Row headerRow = sheet.createRow(0);
        String[] headers = {"一级目录","二级目录","三级目录","四级目录","五级目录","图例id","图例名","是否可作为隔离边界", "图例"};
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
            cell.setCellStyle(headerStyle); // 应用标题样式
        }

        ComponentInfoExcel componentInfoExcel;
        for (int i = 0; i < dataList.size(); i++) {
            log.info((i+1)+"/"+dataList.size()+"行数据开始写入");
            componentInfoExcel = dataList.get(i);
            Row row = sheet.createRow(i + 1);
            String[] strArray = componentInfoExcel.getRealName().split(",");
            for (int j = 0; j < 9; j++) {
                Cell cell = row.createCell(j);
                if(strArray.length -1 > j){
                    cell.setCellValue(strArray[j]);
                }
                if(j == 5){
                    cell.setCellValue(componentInfoExcel.getId());
                }
                if(j == 6){
                    cell.setCellValue(componentInfoExcel.getComponentName());
                }
                if(j == 7){
                }
                cell.setCellStyle(dataStyle); // 应用数据样式
            }

            // 插入图片
            if(StringUtils.isNotEmpty(componentInfoExcel.getComponentXml())){
                insertImageToSheet(sheet, componentInfoExcel.getComponentXml(), i + 1, 8,picStyle);
            }
            log.info((i+1)+"/"+dataList.size()+"行数据写入完成");
        }

        return workbook;
    }

    /**
     * 将图片插入单元格
     */
    private static void insertImageToSheet(Sheet sheet, String svgXml, int rowNum, int colNum,CellStyle picStyle) {
        // 下载图片
//        String str = "<svg viewBox=\"0 0 0 0\" id=\"svg1207\" rotate=\"base\" tags=\"H,V\" inkscape:version=\"1.2.2 (732a01da63, 2022-12-09)\" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\" xmlns=\"http://www.w3.org/2000/svg\"><defs defs=\"defs1207\"/></svg>\n";
        BufferedImage originalImage = convertSVGToImage(svgXml);
        if (Objects.isNull(originalImage)) {
            return;
        }

        // 缩放图片
        ScaledImageDataDTO scaledImageData = scaleImage(originalImage);

        // 将缩放后的图片转换为 bytes
        byte[] imageBytes = processImageToBytes(scaledImageData.getScaledImage());

        // 将图片 bytes 添加到 Excel 中
        setIntoSheet(sheet, rowNum, colNum, imageBytes, scaledImageData.getHeight(),picStyle);
    }

//    /**
//     * 下载图片
//     */
//    private static BufferedImage downloadImage(String imagePath) {
//        try {
//            File file = new File(imagePath);
//            return ImageIO.read(file);
//        } catch (IOException e) {
//            e.printStackTrace();
//            return null;
//        }
//    }

    /**
     * svg转image
     * @param svgXml
     * @return
     */
    public static BufferedImage convertSVGToImage(String svgXml) {
        try{
            if(!svgXml.contains("xmlns=\"http://www.w3.org/2000/svg\"")){
                log.error("SVG字符串缺少正确的命名空间:"+svgXml);
                return null;
            }
            TranscoderInput input = new TranscoderInput(new ByteArrayInputStream(svgXml.getBytes()));
            PNGTranscoder t = new PNGTranscoder();
            OutputStream osStream = new ByteArrayOutputStream();
            TranscoderOutput output = new TranscoderOutput(osStream);
            t.transcode(input,output);
            osStream.flush();
            byte[] imageBytes = ((ByteArrayOutputStream) osStream).toByteArray();
            return ImageIO.read(new ByteArrayInputStream(imageBytes));
        }catch (TranscoderException | IOException e) {
            e.printStackTrace();
        } catch (Exception e){
            log.error("SVG字符串解析失败:"+svgXml);
            return null;
        }
        return null;
    }


    /**
     * 缩放图片
     */
    private static ScaledImageDataDTO scaleImage(BufferedImage targetImage) {
        if(targetImage.getWidth() < 200){
            return new ScaledImageDataDTO(targetImage.getHeight(), targetImage);
        }
        int desiredWidth = 200; // 图片宽度
        double aspectRatio = (double) targetImage.getHeight() / targetImage.getWidth();
        int desiredHeight = (int) (desiredWidth * aspectRatio); // 保持纵横比
        BufferedImage scaledImage = Scalr.resize(targetImage, Scalr.Method.QUALITY, Scalr.Mode.FIT_EXACT, desiredWidth, desiredHeight, Scalr.OP_ANTIALIAS);

        return new ScaledImageDataDTO(desiredHeight, scaledImage);
    }

    /**
     * 图片转 bytes
     */
    public static byte[] processImageToBytes(BufferedImage targetImage) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        try {
            ImageIO.write(targetImage, "png", stream);
            return stream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            return new byte[0];
        }
    }

    /**
     * 将图片 bytes 添加到 Excel 中
     */
    private static void setIntoSheet(Sheet sheet, int rowNum, int colNum, byte[] imageBytes, int imageHeight,CellStyle picStyle) {
        int pictureIdx = sheet.getWorkbook().addPicture(imageBytes, Workbook.PICTURE_TYPE_PNG);
        CreationHelper helper = sheet.getWorkbook().getCreationHelper();
        Drawing<?> drawing = sheet.createDrawingPatriarch();
        ClientAnchor anchor = helper.createClientAnchor();
        anchor.setCol1(colNum);
        anchor.setRow1(rowNum);

        Picture pict = drawing.createPicture(anchor, pictureIdx);
        // 设置行高度以匹配图片高度
        Row row = sheet.getRow(rowNum);
        if(imageHeight < 100){
            row.setHeightInPoints(100);
        }else{
            row.setHeightInPoints((float) (imageHeight * 0.75));
        }
        pict.resize();
    }


}
